import argparse
import os
import re
import subprocess
import glob
import multiprocessing
from datetime import datetime
from multiprocessing import Pool
import sys
import tqdm
from pathlib import Path
from natsort import natsorted

# 全局变量控制详细输出
verbose = False

def log_verbose(message):
    """打印详细日志信息"""
    if verbose:
        print(f"[VERBOSE] {message}")

def get_timestamp():
    """获取当前时间戳，格式为%Y.%m.%d_%H.%M.%S"""
    return datetime.now().strftime("%Y.%m.%d_%H.%M.%S")

def find_files(input_paths, regex_pattern, file_type='all', recursive=False):
    """根据输入路径、正则表达式和文件类型查找文件"""
    files = []
    pattern = re.compile(regex_pattern)

    log_verbose(f"开始查找文件，正则表达式: {regex_pattern}, 文件类型: {file_type}, 递归模式: {recursive}")

    for input_path in input_paths:
        log_verbose(f"处理输入路径: {input_path}")

        if os.path.isfile(input_path):
            # 如果是单个文件
            log_verbose(f"检测到单个文件: {input_path}")
            # 根据文件类型过滤
            if file_type == 'dir':
                log_verbose(f"跳过文件（仅处理目录模式）: {input_path}")
                continue

            filename = os.path.abspath(input_path)
            files.append(filename)
            log_verbose(f"添加文件: {filename}")
        elif os.path.isdir(input_path):
            # 如果是目录
            log_verbose(f"检测到目录: {input_path}")
            
            if recursive:
                # 递归遍历目录
                log_verbose(f"开始递归遍历目录: {input_path}")
                for root, dirs, filenames in os.walk(input_path):
                    log_verbose(f"遍历目录: {root}")
                    
                    # 处理目录
                    if file_type in ['dir', 'all']:
                        for dirname in dirs:
                            full_dir_path = os.path.abspath(os.path.join(root, dirname))
                            files.append(full_dir_path)
                            log_verbose(f"添加目录: {full_dir_path}")
                    
                    # 处理文件
                    if file_type in ['file', 'all']:
                        for filename in filenames:
                            full_file_path = os.path.abspath(os.path.join(root, filename))
                            files.append(full_file_path)
                            log_verbose(f"添加文件: {full_file_path}")
            else:
                # 非递归模式，只遍历当前目录
                for f in os.listdir(input_path):
                    filename = os.path.abspath(os.path.join(input_path, f))
                    if file_type == 'dir' and os.path.isdir(filename):
                        files.append(filename)
                        log_verbose(f"添加目录: {filename}")
                    elif file_type == 'file' and os.path.isfile(filename):
                        files.append(filename)
                        log_verbose(f"添加文件: {filename}")
                    elif file_type == 'all':
                        files.append(filename)
                        log_verbose(f"添加文件/目录: {filename}")
    
    log_verbose(f"总共找到 {len(files)} 个文件")
    # 使用正则表达式匹配文件路径
    files = [path for path in files if pattern.search(path)]
    log_verbose(f"匹配文件数量: {len(files)}")
    return files


def execute_command(command):
    """执行单个命令"""
    try:
        print(f"command: {command}")
        result = subprocess.run(command, shell=True, capture_output=True, text=True)

        log_verbose(f"命令执行完成，返回码: {result.returncode}")
        log_verbose(f"标准输出长度: {len(result.stdout) if result.stdout else 0} 字符")
        log_verbose(f"标准错误长度: {len(result.stderr) if result.stderr else 0} 字符")

        if result.returncode == 0:
            if result.stdout:
                log_verbose(f"输出: {result.stdout}")
        else:
            print(f"execute failed command: {command}")
            if result.stderr:
                log_verbose(f"错误: {result.stderr}")

        return result.returncode == 0

    except Exception as e:
        print(f"✗ 执行命令时发生异常: {command}")
        print(f"异常信息: {str(e)}")
        return False

def print_args(args):
    """打印命令行参数"""
    print("\n命令行参数:")
    for k, v in vars(args).items():
        print(f"{k}: {v}")
        print("-"*50)
    
def main():
    global verbose

    # 创建argparse解析器
    parser = argparse.ArgumentParser(
        description="vst_plot_filter",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
示例用法:

"""
    )

    # 添加命令行参数
    parser.add_argument('input',
                       nargs='+',
                       help='输入文件路径列表，支持文件、目录或通配符')

    parser.add_argument('-r', '--regex',
                       default=".*",
                       help='正则表达式过滤器，用于匹配文件名或目录名')

    parser.add_argument('-e', '--execute',
                       action='store_true',
                       help='生成命令后是否执行，默认不执行')
    
    parser.add_argument('--verbose', '-v',
                        action='store_true',
                        help='启用详细日志模式')
    
    
    parser.add_argument('-f', '--flags',
                        type=str,
                        nargs='+',
                        help='对应input file的flag参数')
    
    parser.add_argument('-t', '--title',
                        type=str,
                        help='标题')
    parser.add_argument('--not_sorted', action='store_true', help='不要对过滤文件进行自动排序')
    
    parser.add_argument('-s','--line_styles', 
                        type=str, 
                        nargs='*', 
                        choices=['solid', 'dashed', 'dashdot', 'dotted'], 
                        help='多文件模式下的线形列表（与inputs一一对应）')
    parser.add_argument('--xlim', type=str, 
                       help='X轴数据范围设置。格式: start:end，支持数字和日期。'
                            '数字示例: --xlim 0:100；'
                            '日期示例: --xlim "2025.08.04_15.48.09:2025.08.04_16.48.09" (需配合-xf使用)')
    
    parser.add_argument('--ylim', type=str, nargs='*', 
                       help='Y轴数据范围设置。格式: field:start:end。'
                            '例如: --ylim VST1_T_sensor:40:70 attenuation:0.8:1.0')
    parser.add_argument('-l','--hlines', type=str, nargs='*',
                       help='水平参考线设置。格式: field:value 或 field:value:"名称"。例如: VST1_T_sensor:40 VST1_T_sensor:50:"目标温度" Y_std:35:"标准值"')
    parser.add_argument('-c','--colors', type=int, nargs='*', help='颜色索引列表(与inputs一一对应),从color_list中选择颜色。例如: -c 0 3 5 表示使用第0、3、5个颜色')
    parser.add_argument('-n', '--notes', type=str, nargs='*',
                    help='节点标注设置。格式: "缺省消息" 或 position:"消息" 或 position:color:"消息"。'
                    '位置选项: lt(左上), rt(右上), rb(右下), lb(左下), lc(左中), rc(右中), ct(中上), cb(中下)。支持\\n换行符。'
                    '例如: -n "默认消息" -n lt:"左上角\\n第二行" -n rt:#FF0000:"红色右上角" -n lc:"左中位置"')
    
    parser.add_argument('-o', '--output',
                        type=str,
                        help='输出文件路径，默认为当前目录下的 output.txt')

    # 解析参数
    args = parser.parse_args()

    # 设置全局verbose标志
    verbose = args.verbose

    if verbose:
        log_verbose("启用详细日志模式")
        log_verbose(f"解析的参数: {vars(args)}")

    log_verbose("=== 批量命令生成工具 ===")
    log_verbose(f"输入路径: {args.input}")
    log_verbose(f"正则表达式: {args.regex}")
    log_verbose("开始文件查找")
    matched_files = find_files(args.input, args.regex, 'file', True)
    if not args.not_sorted:
        matched_files = natsorted(matched_files)
    # 正则匹配的文件
    # 生成命令
    log_verbose("开始命令生成")
    flags = []
    directions = []
    
    for path in matched_files:
        names = list(Path(path).parts)
        flag = None
        direction = None
        for i in range(1, len(names)+1):
            res = re.search(r'(left|right)_analysis', names[-i])
            if res:
                direction = res.group(1)
                flag = names[-i-1]
                flags.append(flag)
                directions.append(direction)
                continue
        if flag is None:
            print_args(args)
            raise(Exception(f'没有找到left_analysis或者right_analysis标签! path:{path}'))
            
    
    if len(set(directions)) > 1:
        print_args(args)
        raise(Exception(f'left_analysis和right_analysis不能同时存在！ path:{path}'))
    files_str = ' '.join(matched_files)
    if args.flags:
        flags_str = ' '.join(args.flags)
    else:    
        flags_str = ' '.join(flags)
    
    print(f'matched_files:')
    for f in matched_files:
        print(f)
    print(f'flags:')
    print(flags_str)
    y_fields_str = 'VST1_T_sensor' if directions[0] == 'left' else 'VST2_T_sensor'
    direction_str = 'left' if directions[0] == 'left' else 'right'
    command = f'line_plotter.bat {files_str} -f {flags_str} -xf none -xd none -x minute -y {y_fields_str} Y_std attenuation --labels minute:时间(分钟) VST1_T_sensor:温度  VST2_T_sensor:温度 Y_std:对比度 attenuation:衰减率'
    output_path = None
    if args.output:
        out_base_name = os.path.splitext(os.path.basename(args.output))[0]
        if re.search(out_base_name, r'.*(left|right)$', re.IGNORECASE):
            output_path = args.output
        else:
            output_path = os.path.dirname(args.output) + '/' + out_base_name + '-' + directions[0] + '.png'
        command += f' -o {output_path}'
    if args.line_styles:
        command += f' --line_style {" ".join(args.line_styles)}'
    if args.hlines:
        command += f' --hlines {" ".join(args.hlines)}'
    if args.colors:
        command += f' --colors {" ".join([str(i) for i in args.colors])}'
    if args.notes:
        command += f' --notes {" ".join(args.notes)}'
    if args.xlim:
        command += f' --xlim {args.xlim}'
    if args.ylim:
        command += f' --ylim {" ".join(args.ylim)}'
    if args.title:
        command += f' --title {args.title}-{directions[0]}'
    elif output_path:
        command += f' --title {os.path.splitext(os.path.basename(output_path))[0]}'
    
    # 执行命令
    if args.execute:
        print("execute...")
        if execute_command(command):
            print("execute success!")
        else:
            print("execute failed!")
        sys.exit(1)
    else:
        print(f'command: {command}\n')

if __name__ == "__main__":
    main()
